package com.newmainsoftech.dao;

import javax.naming.NamingException;

import org.junit.AfterClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

import com.newmainsoftech.dao.entity.AbstractEntityIdentifierImplTest;
import com.newmainsoftech.dao.entity.relation.EntityBiLinkCollectionProxyImplWithVariableHashEntityTest;
import com.newmainsoftech.dao.entity.relation.FundamentalCascadeTest;
import com.newmainsoftech.eatestutil.container.AbstractEjbContainerMateImpl;
import com.newmainsoftech.eatestutil.container.EjbContainerMate;
import com.newmainsoftech.eatestutil.container.EjbContextCloseHandler;
import com.newmainsoftech.injection.Swap;

@RunWith( Suite.class)
@SuiteClasses( value = {
		FundamentalCascadeTest.class,
		AbstractEntityIdentifierImplTest.class, 
		EntityBiLinkCollectionProxyImplWithVariableHashEntityTest.class
})
public class EjbTestManager {
	@Swap( isOnlyForNull=true)
	private static AbstractEjbContainerMateImpl ejbContainerMate;
		protected static void setEjbContainerMate( final AbstractEjbContainerMateImpl ejbContainerMate) {
			EjbTestManager.ejbContainerMate = ejbContainerMate;
		}
		public static EjbContextCloseHandler getEjbContextCloseHandler() {
			return ejbContainerMate;
		}
		private static boolean isRegistered = false;
		public static EjbContainerMate getEjbContainerMate() {
			if ( !isRegistered) {
				getEjbContextCloseHandler().registerConsumer( EjbTestManager.class);
				getEjbContextCloseHandler().setClosedByNonConsumer( true);
				getEjbContextCloseHandler().setContainerClosedToo( true);
				isRegistered = true;
			}
			return ejbContainerMate;
		}
		
	@AfterClass
	public static void staticTearDown() throws Exception {
		getEjbContextCloseHandler().removeConsumer( EjbTestManager.class);
			if ( getEjbContextCloseHandler().getConsumerCount() < 1) {
				final long duration 
				= 100 + ejbContainerMate.getCloseDelay() 
					+ ejbContainerMate.getCloseHandler().getCloseLockAcquireTimeOutDefaultvValue();
				try {
					Thread.sleep( duration);
				} 
				catch( InterruptedException exception) {
					Thread.currentThread().interrupt();
				}
			}
	}
	
	public static <T> T lookupBy( final Class<T> type) throws NamingException {
		return getEjbContainerMate().contextLookup( type);
	}
	
	public static <T> T lookupBy( final Class<?> implClass, final Class<T> interfaceClass) 
	throws NamingException {
		return getEjbContainerMate().contextLookup( implClass, interfaceClass);
	}
}
